package com.auto.survey.activity.monitoring.entity

import android.os.Parcel
import android.os.Parcelable
import androidx.room.Entity
import androidx.room.ForeignKey
import androidx.room.Index
import androidx.room.PrimaryKey
import com.android.identity.util.UUID

/**
 * 测点实体类，对应数据库中MonitoringPoint表
 * 测站下的测点
 * 每个测点属于一个特定监测对象和特定的测站，此类是参与实际测量的测点
 */
@Entity(
    tableName = "MonitoringPoint",
    foreignKeys = [
        ForeignKey(
            entity = MonitoringObject::class,
            parentColumns = ["id"],
            childColumns = ["monitoringObjectId"],
            onDelete = ForeignKey.CASCADE
        ),
        ForeignKey(
            entity = MonitoringStation::class,
            parentColumns = ["id"],
            childColumns = ["stationId"],
            onDelete = ForeignKey.CASCADE
        )
    ],
    indices = [Index(value = ["monitoringObjectId"]), Index(value = ["stationId"])]
)
data class MonitoringPoint(
    /**
     * 测点ID，主键，自增长
     */
    @PrimaryKey(autoGenerate = true) var id: Int = 0,
    /**
     * 所属监测对象ID，外键关联ATS_Monitoring表
     */
    val monitoringObjectId: Int,

    /**
     * 所属站点ID，外键关联Station表
     */
    val stationId: Int, // 新增外键字段

    /**
     * 测点名称
     */
    val pointName: String,
    /**
     * 测点编码
     */
    val pointCode: String = UUID.randomUUID().toString(),
    /**
     * 测点X坐标
     */
    var pointX: Double,
    /**
     * 测点Y坐标
     */
    var pointY: Double,
    /**
     * 测点Z坐标（高程）
     */
    var pointZ: Double,
    /**
     * 水平角
     */
    var pointHz:Double?,

    /**
     * 棱镜高
     */
    var mirrorHeight: Double,

    /**
     * 棱镜类型:圆棱镜、反射片等
     */
    var mirrorType:Int,

    /**
     * 是否已经采集数据
     */
    var collected:Boolean,

    /**
     * 垂直角
     */
    var pointV:Double?,
    /**
     * 斜距
     */
    var pointSD:Double?,
    /**
     * 测点类型（控制点、测点）
     */
    val pointType: String,

    /**
     * 是否报警（true:报警，false:正常）
     */
    var isWarning: Boolean = false,
    /**
     * 创建时间，格式：YYYY-MM-DD HH:MM:SS
     */
    val createTime: String,
    /**
     * 更新时间，格式：YYYY-MM-DD HH:MM:SS
     */
    var updateTime: String,
    /**
     * 测量顺序，用于控制测量点的观测顺序
     */
    var measurementOrder: Int = 0
): Parcelable {

    constructor(parcel: Parcel) : this(
        parcel.readInt(),
        parcel.readInt(),
        parcel.readInt(),
        parcel.readString() ?: "",
        parcel.readString() ?: "",
        parcel.readDouble(),
        parcel.readDouble(),
        parcel.readDouble(),
        // 用Byte替代Boolean读取：1表示非空，0表示空
        if (parcel.readByte() == 1.toByte()) parcel.readDouble() else null,
        parcel.readDouble(),
        parcel.readInt(),
        parcel.readByte() != 0.toByte(),
        // 用Byte替代Boolean读取
        if (parcel.readByte() == 1.toByte()) parcel.readDouble() else null,
        // 用Byte替代Boolean读取
        if (parcel.readByte() == 1.toByte()) parcel.readDouble() else null,
        parcel.readString() ?: "",
        parcel.readByte() != 0.toByte(),
        parcel.readString() ?: "",
        parcel.readString() ?: "",
        parcel.readInt()
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeInt(id)
        parcel.writeInt(monitoringObjectId)
        parcel.writeInt(stationId)
        parcel.writeString(pointName)
        parcel.writeString(pointCode)
        parcel.writeDouble(pointX)
        parcel.writeDouble(pointY)
        parcel.writeDouble(pointZ)
        // 用Byte替代Boolean写入：1表示非空，0表示空
        parcel.writeByte(if (pointHz != null) 1 else 0)
        pointHz?.let { parcel.writeDouble(it) }
        parcel.writeDouble(mirrorHeight)
        parcel.writeInt(mirrorType)
        parcel.writeByte(if (collected) 1 else 0)
        // 用Byte替代Boolean写入
        parcel.writeByte(if (pointV != null) 1 else 0)
        pointV?.let { parcel.writeDouble(it) }
        // 用Byte替代Boolean写入
        parcel.writeByte(if (pointSD != null) 1 else 0)
        pointSD?.let { parcel.writeDouble(it) }
        parcel.writeString(pointType)
        parcel.writeByte(if (isWarning) 1 else 0)
        parcel.writeString(createTime)
        parcel.writeString(updateTime)
        parcel.writeInt(measurementOrder)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<MonitoringPoint> {
        override fun createFromParcel(parcel: Parcel): MonitoringPoint {
            return MonitoringPoint(parcel)
        }

        override fun newArray(size: Int): Array<MonitoringPoint?> {
            return arrayOfNulls(size)
        }
    }

    // 扩展函数：比较Point和CheckPoint的坐标是否相同
    fun hasSameCoordinates(checkPoint: MonitorCheckPoint): Boolean {
        return pointHz == checkPoint.checkPointHz &&
                pointV == checkPoint.checkPointV &&
                pointSD == checkPoint.checkPointSD &&
                pointX == checkPoint.checkPointX &&
                pointY == checkPoint.checkPointY &&
                pointZ == checkPoint.checkPointZ
    }

}